package com.socket.client.manager;

import com.socket.client.feign.SysGroupApi;
import com.socket.client.feign.param.GroupParam;
import com.socket.client.model.chat.ChatMessage;
import com.socket.client.model.chat.ChatUser;
import com.socket.client.model.chat.SysGroup;
import com.socket.core.model.command.BaseCommand;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * Socket群组管理器
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class GroupManager extends ConcurrentHashMap<String, List<ChatUser>> {
    private final Map<String, SysGroup> map = new ConcurrentHashMap<>();
    private final UserManager userManager;
    private final SysGroupApi sysGroupApi;

    /**
     * 向群组发送消息
     *
     * @param message 消息
     */
    public void sendGroup(ChatMessage message) {
        String target = message.getTarget();
        getGroupUsers(target).forEach(t -> t.send(message));
    }

    /**
     * 获取指定群组ID成员列表
     *
     * @param gid 群组id
     * @return 成员列表
     */
    public List<ChatUser> getGroupUsers(String gid) {
        List<ChatUser> users = this.get(gid);
        // 群组用户不存在 尝试从远程获取
        if (users == null) {
            this.getGroup(gid);
        }
        users = this.get(gid);
        return users == null ? new ArrayList<>() : users;
    }

    /**
     * 获取群组对象
     *
     * @param gid 群组id
     * @return 群组信息
     */
    public SysGroup getGroup(String gid) {
        return Optional.ofNullable(gid).map(map::get).orElseGet(() -> {
            GroupParam param = new GroupParam();
            param.setGid(gid);
            SysGroup data = sysGroupApi.detail(param).getData();
            // 写入缓存
            Optional.ofNullable(data).ifPresent(e -> {
                log.debug("同步缓存群组：{}", gid);
                map.put(e.getGuid(), e);
                List<ChatUser> collect = e.getGuids()
                        .stream()
                        .map(userManager::getUser)
                        .filter(Objects::nonNull)
                        .collect(Collectors.toList());
                super.put(e.getGuid(), collect);
            });
            return data;
        });
    }

    /**
     * 向群组发送系统消息<br>
     *
     * @param gid     群id
     * @param content 消息内容
     * @param command 消息类型
     * @param data    额外数据
     */
    public void sendGroup(String gid, String content, BaseCommand<?> command, Object data) {
        getGroupUsers(gid).forEach(user -> user.send(content, command, data));
    }

    @Override
    public List<ChatUser> remove(@NonNull Object key) {
        map.remove(key);
        return super.remove(key);
    }
}
